package com.dengpp.pdform.view;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.ScaleGestureDetector;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.AspectRatio;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraControl;
import androidx.camera.core.CameraInfo;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.dengpp.pdform.R;
import com.dengpp.pdform.model.LocationInfo;
import com.dengpp.pdform.model.MediaFile;
import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CameraXActivity extends AppCompatActivity {
    private static final String TAG = "CameraXActivity";

    private PreviewView previewView;
    private Button btnCapture;
    private Button btnCancel;
    private Button btnSwitchCamera;
    private TextView tvLocation;
    private TextView tvZoom;

    private ExecutorService cameraExecutor;
    private ImageCapture imageCapture;
    private Camera camera;
    private CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

    private LocationManager locationManager;
    private LocationListener locationListener;
    private LocationInfo currentLocation;
    private boolean isLocationReceived = false;

    // 缩放相关
    private float currentZoomLevel = 1.0f;
    private float initialFingerSpacing = 0f;
    private ScaleGestureDetector scaleGestureDetector;

    public static void start(AppCompatActivity activity, int requestCode) {
        Intent intent = new Intent(activity, CameraXActivity.class);
        activity.startActivityForResult(intent, requestCode);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_x);

        initViews();
        startLocationUpdates();

        // 请求相机权限
        if (allPermissionsGranted()) {
            startCamera();
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 10);
        }

        // 创建单线程执行器
        cameraExecutor = Executors.newSingleThreadExecutor();
    }

    private void initViews() {
        previewView = findViewById(R.id.previewView);
        btnCapture = findViewById(R.id.btn_capture);
        btnCancel = findViewById(R.id.btn_cancel);
        btnSwitchCamera = findViewById(R.id.btn_switch_camera);
        tvLocation = findViewById(R.id.tv_location);
        tvZoom = findViewById(R.id.tv_zoom);

        btnCapture.setOnClickListener(v -> takePhoto());
        btnCancel.setOnClickListener(v -> finish());
        btnSwitchCamera.setOnClickListener(v -> switchCamera());

        // 设置缩放手势
        scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener());

        previewView.setOnTouchListener((v, event) -> {
            scaleGestureDetector.onTouchEvent(event);
            return true;
        });
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            if (camera != null) {
                CameraInfo cameraInfo = camera.getCameraInfo();
                CameraControl cameraControl = camera.getCameraControl();

                float currentZoomRatio = cameraInfo.getZoomState().getValue().getZoomRatio();
                float newZoomRatio = currentZoomRatio * detector.getScaleFactor();

                // 限制缩放范围
                float minZoomRatio = cameraInfo.getZoomState().getValue().getMinZoomRatio();
                float maxZoomRatio = cameraInfo.getZoomState().getValue().getMaxZoomRatio();
                newZoomRatio = Math.max(minZoomRatio, Math.min(newZoomRatio, maxZoomRatio));
                currentZoomLevel = newZoomRatio;
                updateZoomText();
                cameraControl.setZoomRatio(newZoomRatio);
            }
            return true;
        }
    }

    private void switchCamera() {
        if (cameraSelector == CameraSelector.DEFAULT_BACK_CAMERA) {
            cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;
        } else {
            cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
        }
        startCamera();
    }

    private void takePhoto() {
        if (imageCapture == null) {
            Toast.makeText(this, "相机未准备好", Toast.LENGTH_SHORT).show();
            return;
        }

        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
        String fileName = "IMG_" + timeStamp + ".jpg";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        if (storageDir == null) {
            storageDir = getFilesDir();
        }

        // 确保目录存在
        if (!storageDir.exists()) {
            storageDir.mkdirs();
        }

        File photoFile = new File(storageDir, fileName);

        ImageCapture.OutputFileOptions outputFileOptions =
                new ImageCapture.OutputFileOptions.Builder(photoFile).build();

        imageCapture.takePicture(outputFileOptions, cameraExecutor,
                new ImageCapture.OnImageSavedCallback() {
                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                        runOnUiThread(() -> {
                            Uri savedUri = Uri.fromFile(photoFile);
                            MediaFile mediaFile = new MediaFile(savedUri.toString(), MediaFile.MediaType.IMAGE);
                            mediaFile.setName("d_" + timeStamp);
                            if (isLocationReceived && currentLocation != null) {
                                mediaFile.setLocationInfo(currentLocation);
                            }

                            Intent resultIntent = new Intent();
                            resultIntent.putExtra("media_file", mediaFile);
                            setResult(RESULT_OK, resultIntent);
                            finish();
                        });
                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {
                        runOnUiThread(() -> {
                            Log.e(TAG, "拍照失败: " + exception.getMessage(), exception);
                            Toast.makeText(CameraXActivity.this, "拍照失败: " + exception.getMessage(), Toast.LENGTH_SHORT).show();
                        });
                    }
                });
    }

    private void startCamera() {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

                // 预览
                Preview preview = new Preview.Builder()
                        .setTargetAspectRatio(AspectRatio.RATIO_16_9)
                        .build();

                // 拍照
                imageCapture = new ImageCapture.Builder()
                        .setTargetAspectRatio(AspectRatio.RATIO_16_9)
                        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                        .build();

                // 先解绑所有用例
                cameraProvider.unbindAll();

                // 绑定到生命周期
                camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);

                // 设置预览
                preview.setSurfaceProvider(previewView.getSurfaceProvider());

                // 更新缩放文本
                updateZoomText();

            } catch (ExecutionException | InterruptedException e) {
                Log.e(TAG, "启动相机失败", e);
                runOnUiThread(() -> Toast.makeText(CameraXActivity.this, "启动相机失败", Toast.LENGTH_SHORT).show());
            }
        }, ContextCompat.getMainExecutor(this));
    }

    private void updateZoomText() {
        if (tvZoom != null) {
            tvZoom.setText(String.format("缩放: %.1fx", currentZoomLevel));
        }
    }

    private void startLocationUpdates() {
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                if (location != null) {
                    currentLocation = new LocationInfo(location.getLatitude(), location.getLongitude());
                    isLocationReceived = true;
                    updateLocationText();
                    Log.d(TAG, "位置更新: " + currentLocation.toString());
                }
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            @Override
            public void onProviderEnabled(String provider) {
            }

            @Override
            public void onProviderDisabled(String provider) {
            }
        };

        // 请求位置更新
        try {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 1, locationListener);
        } catch (SecurityException e) {
            Log.e(TAG, "位置权限异常", e);
        }

        // 获取最后一次已知位置
        try {
            Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if (lastKnownLocation == null) {
                lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            }

            if (lastKnownLocation != null) {
                currentLocation = new LocationInfo(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
                isLocationReceived = true;
                updateLocationText();
            }
        } catch (SecurityException e) {
            Log.e(TAG, "获取位置失败", e);
        }
    }

    private void updateLocationText() {
        if (tvLocation != null && currentLocation != null) {
            tvLocation.setText(String.format("位置: %.6f, %.6f",
                    currentLocation.getLatitude(), currentLocation.getLongitude()));
        }
    }

    private boolean allPermissionsGranted() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 10) {
            if (allPermissionsGranted()) {
                startCamera();
            } else {
                Toast.makeText(this, "需要相机权限", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (cameraExecutor != null) {
            cameraExecutor.shutdown();
        }
        if (locationManager != null && locationListener != null) {
            try {
                locationManager.removeUpdates(locationListener);
            } catch (SecurityException e) {
                Log.e(TAG, "移除位置监听失败", e);
            }
        }
    }
}
